From c3a9599044ea362334d9c978ddff0b1a806b7e96 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 5 Feb 2016 15:14:17 -0800 Subject: [PATCH] Implement a local registry type This flavor of registry is intended to behave very similarly to the standard remote registry, except everything is contained locally on the filesystem instead. There are a few components to this new flavor of registry: 1. The registry itself is rooted at a particular directory, owning all structure beneath it. 2. There is an `index` folder with the same structure as the crates.io index describing the local registry (e.g. contents, versions, checksums, etc). 3. Inside the root will also be a list of `.crate` files which correspond to those described in the index. All crates must be of the form `name-version.crate` and be the same `.crate` files from crates.io itself. This support can currently be used via the previous implementation of source overrides with the new type: ```toml [source.crates-io] replace-with = 'my-awesome-registry' [source.my-awesome-registry] local-registry = 'path/to/registry' ``` I will soon follow up with a tool which can be used to manage these local registries externally. --- src/cargo/core/source.rs | 22 +- src/cargo/sources/config.rs | 14 +- src/cargo/sources/registry/index.rs | 9 +- src/cargo/sources/registry/local.rs | 92 +++++++ src/cargo/sources/registry/mod.rs | 11 +- src/cargo/sources/registry/remote.rs | 4 + tests/bad-config.rs | 36 +-- tests/cargotest/support/mod.rs | 3 +- tests/cargotest/support/registry.rs | 50 ++-- tests/local-registry.rs | 343 +++++++++++++++++++++++++++ tests/registry.rs | 24 +- 11 files changed, 541 insertions(+), 67 deletions(-) create mode 100644 src/cargo/sources/registry/local.rs create mode 100644 tests/local-registry.rs diff --git a/src/cargo/core/source.rs b/src/cargo/core/source.rs index b8b89f600..93e223a29 100644 --- a/src/cargo/core/source.rs +++ b/src/cargo/core/source.rs @@ -62,6 +62,8 @@ enum Kind { Path, /// represents the central registry Registry, + /// represents a local filesystem-based registry + LocalRegistry, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -167,6 +169,9 @@ impl SourceId { SourceIdInner { kind: Kind::Registry, ref url, .. } => { format!("registry+{}", url) } + SourceIdInner { kind: Kind::LocalRegistry, ref url, .. } => { + format!("local-registry+{}", url) + } } } @@ -184,6 +189,11 @@ impl SourceId { SourceId::new(Kind::Registry, url.clone()) } + pub fn for_local_registry(path: &Path) -> CargoResult { + let url = try!(path.to_url()); + Ok(SourceId::new(Kind::LocalRegistry, url)) + } + /// Returns the `SourceId` corresponding to the main repository. /// /// This is the main cargo registry by default, but it can be overridden in @@ -213,7 +223,7 @@ impl SourceId { self.inner.kind == Kind::Path } pub fn is_registry(&self) -> bool { - self.inner.kind == Kind::Registry + self.inner.kind == Kind::Registry || self.inner.kind == Kind::LocalRegistry } pub fn is_git(&self) -> bool { @@ -236,6 +246,13 @@ impl SourceId { Box::new(PathSource::new(&path, self, config)) } Kind::Registry => Box::new(RegistrySource::remote(self, config)), + Kind::LocalRegistry => { + let path = match self.inner.url.to_file_path() { + Ok(p) => p, + Err(()) => panic!("path sources cannot be remote"), + }; + Box::new(RegistrySource::local(self, &path, config)) + } } } @@ -321,7 +338,8 @@ impl fmt::Display for SourceId { } Ok(()) } - SourceIdInner { kind: Kind::Registry, ref url, .. } => { + SourceIdInner { kind: Kind::Registry, ref url, .. } | + SourceIdInner { kind: Kind::LocalRegistry, ref url, .. } => { write!(f, "registry {}", url) } } diff --git a/src/cargo/sources/config.rs b/src/cargo/sources/config.rs index 0cde9e5e1..3be515645 100644 --- a/src/cargo/sources/config.rs +++ b/src/cargo/sources/config.rs @@ -128,11 +128,21 @@ a lock file compatible with `{orig}` cannot be generated in this situation let url = try!(url(val, &format!("source.{}.registry", name))); srcs.push(SourceId::for_registry(&url)); } + if let Some(val) = table.get("local-registry") { + let (s, path) = try!(val.string(&format!("source.{}.local-registry", + name))); + let mut path = path.to_path_buf(); + path.pop(); + path.pop(); + path.push(s); + srcs.push(try!(SourceId::for_local_registry(&path))); + } let mut srcs = srcs.into_iter(); let src = try!(srcs.next().chain_error(|| { - human(format!("no source URL specified for `source.{}`, needs \ - `registry` defined", name)) + human(format!("no source URL specified for `source.{}`, need \ + either `registry` or `local-registry` defined", + name)) })); if srcs.next().is_some() { return Err(human(format!("more than one source URL specified for \ diff --git a/src/cargo/sources/registry/index.rs b/src/cargo/sources/registry/index.rs index 7d06ee1af..4aa59aebc 100644 --- a/src/cargo/sources/registry/index.rs +++ b/src/cargo/sources/registry/index.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use std::io::prelude::*; -use std::fs::File; +use std::fs::{File, OpenOptions}; use std::path::Path; use rustc_serialize::json; @@ -52,6 +52,13 @@ impl<'cfg> RegistryIndex<'cfg> { if self.cache.contains_key(name) { return Ok(self.cache.get(name).unwrap()); } + // If the lock file doesn't already exist then this'll cause *someone* + // to create it. We don't actually care who creates it, and if it's + // already there this should have no effect. + drop(OpenOptions::new() + .write(true) + .create(true) + .open(self.path.join(INDEX_LOCK).into_path_unlocked())); let lock = self.path.open_ro(Path::new(INDEX_LOCK), self.config, "the registry index"); diff --git a/src/cargo/sources/registry/local.rs b/src/cargo/sources/registry/local.rs new file mode 100644 index 000000000..6c2966e53 --- /dev/null +++ b/src/cargo/sources/registry/local.rs @@ -0,0 +1,92 @@ +use std::io::SeekFrom; +use std::io::prelude::*; +use std::path::Path; + +use rustc_serialize::hex::ToHex; + +use core::PackageId; +use sources::registry::{RegistryData, RegistryConfig}; +use util::{Config, CargoResult, ChainError, human, Sha256, Filesystem}; +use util::FileLock; + +pub struct LocalRegistry<'cfg> { + index_path: Filesystem, + root: Filesystem, + src_path: Filesystem, + config: &'cfg Config, +} + +impl<'cfg> LocalRegistry<'cfg> { + pub fn new(root: &Path, + config: &'cfg Config, + name: &str) -> LocalRegistry<'cfg> { + LocalRegistry { + src_path: config.registry_source_path().join(name), + index_path: Filesystem::new(root.join("index")), + root: Filesystem::new(root.to_path_buf()), + config: config, + } + } +} + +impl<'cfg> RegistryData for LocalRegistry<'cfg> { + fn index_path(&self) -> &Filesystem { + &self.index_path + } + + fn config(&self) -> CargoResult> { + // Local registries don't have configuration for remote APIs or anything + // like that + Ok(None) + } + + fn update_index(&mut self) -> CargoResult<()> { + // Nothing to update, we just use what's on disk. Verify it actually + // exists though. We don't use any locks as we're just checking whether + // these directories exist. + let root = self.root.clone().into_path_unlocked(); + if !root.is_dir() { + bail!("local registry path is not a directory: {}", + root.display()) + } + let index_path = self.index_path.clone().into_path_unlocked(); + if !index_path.is_dir() { + bail!("local registry index path is not a directory: {}", + index_path.display()) + } + Ok(()) + } + + fn download(&mut self, pkg: &PackageId, checksum: &str) + -> CargoResult { + let crate_file = format!("{}-{}.crate", pkg.name(), pkg.version()); + let mut crate_file = try!(self.root.open_ro(&crate_file, + self.config, + "crate file")); + + // If we've already got an unpacked version of this crate, then skip the + // checksum below as it is in theory already verified. + let dst = format!("{}-{}", pkg.name(), pkg.version()); + if self.src_path.join(dst).into_path_unlocked().exists() { + return Ok(crate_file) + } + + try!(self.config.shell().status("Unpacking", pkg)); + + // We don't actually need to download anything per-se, we just need to + // verify the checksum matches the .crate file itself. + let mut data = Vec::new(); + try!(crate_file.read_to_end(&mut data).chain_error(|| { + human(format!("failed to read `{}`", crate_file.path().display())) + })); + let mut state = Sha256::new(); + state.update(&data); + if state.finish().to_hex() != checksum { + bail!("failed to verify the checksum of `{}`", pkg) + } + + try!(crate_file.seek(SeekFrom::Start(0))); + + Ok(crate_file) + } +} diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index 4b280c0a9..88128f119 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -160,7 +160,7 @@ use std::collections::HashMap; use std::fs::File; -use std::path::PathBuf; +use std::path::{PathBuf, Path}; use flate2::read::GzDecoder; use tar::Archive; @@ -227,6 +227,7 @@ pub trait RegistryData { mod index; mod remote; +mod local; fn short_name(id: &SourceId) -> String { let hash = hex::short_hash(id); @@ -242,6 +243,14 @@ impl<'cfg> RegistrySource<'cfg> { RegistrySource::new(source_id, config, &name, Box::new(ops)) } + pub fn local(source_id: &SourceId, + path: &Path, + config: &'cfg Config) -> RegistrySource<'cfg> { + let name = short_name(source_id); + let ops = local::LocalRegistry::new(path, config, &name); + RegistrySource::new(source_id, config, &name, Box::new(ops)) + } + fn new(source_id: &SourceId, config: &'cfg Config, name: &str, diff --git a/src/cargo/sources/registry/remote.rs b/src/cargo/sources/registry/remote.rs index 28d6ada65..65f09a25f 100644 --- a/src/cargo/sources/registry/remote.rs +++ b/src/cargo/sources/registry/remote.rs @@ -53,6 +53,10 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { } fn update_index(&mut self) -> CargoResult<()> { + // Ensure that this'll actually succeed later on. + try!(ops::http_handle(self.config)); + + // Then we actually update the index try!(self.index_path.create_dir()); let lock = try!(self.index_path.open_rw(Path::new(INDEX_LOCK), self.config, diff --git a/tests/bad-config.rs b/tests/bad-config.rs index d7d0192bd..15324711f 100644 --- a/tests/bad-config.rs +++ b/tests/bad-config.rs @@ -77,8 +77,10 @@ fn bad3() { assert_that(foo.cargo_process("publish").arg("-v"), execs().with_status(101).with_stderr("\ -[UPDATING] registry `[..]` -[ERROR] invalid configuration for key `http.proxy` +error: failed to update registry [..] + +Caused by: + invalid configuration for key `http.proxy` expected a string, but found a boolean for `http.proxy` in [..]config ")); } @@ -555,7 +557,7 @@ fn bad_source_config1() { assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ -error: no source URL specified for `source.foo`, needs [..] +error: no source URL specified for `source.foo`, need [..] ")); } @@ -759,7 +761,6 @@ This will be considered an error in future versions")); } #[test] -#[ignore] fn bad_source_config7() { let p = project("foo") .file("Cargo.toml", r#" @@ -775,7 +776,7 @@ fn bad_source_config7() { .file(".cargo/config", r#" [source.foo] registry = 'http://example.com' - directory = 'file:///another/file' + local-registry = 'file:///another/file' "#); Package::new("bar", "0.1.0").publish(); @@ -785,28 +786,3 @@ fn bad_source_config7() { error: more than one source URL specified for `source.foo` ")); } - -#[test] -#[ignore] -fn bad_source_config8() { - let p = project("foo") - .file("Cargo.toml", r#" - [package] - name = "foo" - version = "0.0.0" - authors = [] - - [dependencies] - bar = "*" - "#) - .file("src/lib.rs", "") - .file(".cargo/config", r#" - [source.foo] - directory = 'file://another/file' - "#); - - assert_that(p.cargo_process("build"), - execs().with_status(101).with_stderr("\ -error: failed to convert `file://another/file` to an absolute path (configured in [..]) -")); -} diff --git a/tests/cargotest/support/mod.rs b/tests/cargotest/support/mod.rs index f493faef6..96f8d2baf 100644 --- a/tests/cargotest/support/mod.rs +++ b/tests/cargotest/support/mod.rs @@ -652,7 +652,8 @@ fn substitute_macros(input: &str) -> String { ("[VERIFYING]", " Verifying"), ("[ARCHIVING]", " Archiving"), ("[INSTALLING]", " Installing"), - ("[REPLACING]", " Replacing") + ("[REPLACING]", " Replacing"), + ("[UNPACKING]", " Unpacking"), ]; let mut result = input.to_owned(); for &(pat, subst) in macros.iter() { diff --git a/tests/cargotest/support/registry.rs b/tests/cargotest/support/registry.rs index 26663e260..da3e12bbf 100644 --- a/tests/cargotest/support/registry.rs +++ b/tests/cargotest/support/registry.rs @@ -27,6 +27,7 @@ pub struct Package { files: Vec<(String, String)>, yanked: bool, features: HashMap>, + local: bool, } struct Dependency { @@ -74,9 +75,15 @@ impl Package { files: Vec::new(), yanked: false, features: HashMap::new(), + local: false, } } + pub fn local(&mut self, local: bool) -> &mut Package { + self.local = local; + self + } + pub fn file(&mut self, name: &str, contents: &str) -> &mut Package { self.files.push((name.to_string(), contents.to_string())); self @@ -162,7 +169,11 @@ impl Package { }; // Write file/line in the index - let dst = registry_path().join(&file); + let dst = if self.local { + registry_path().join("index").join(&file) + } else { + registry_path().join(&file) + }; let mut prev = String::new(); let _ = File::open(&dst).and_then(|mut f| f.read_to_string(&mut prev)); t!(fs::create_dir_all(dst.parent().unwrap())); @@ -170,20 +181,22 @@ impl Package { .write_all((prev + &line[..] + "\n").as_bytes())); // Add the new file to the index - let repo = t!(git2::Repository::open(®istry_path())); - let mut index = t!(repo.index()); - t!(index.add_path(Path::new(&file))); - t!(index.write()); - let id = t!(index.write_tree()); - - // Commit this change - let tree = t!(repo.find_tree(id)); - let sig = t!(repo.signature()); - let parent = t!(repo.refname_to_id("refs/heads/master")); - let parent = t!(repo.find_commit(parent)); - t!(repo.commit(Some("HEAD"), &sig, &sig, - "Another commit", &tree, - &[&parent])); + if !self.local { + let repo = t!(git2::Repository::open(®istry_path())); + let mut index = t!(repo.index()); + t!(index.add_path(Path::new(&file))); + t!(index.write()); + let id = t!(index.write_tree()); + + // Commit this change + let tree = t!(repo.find_tree(id)); + let sig = t!(repo.signature()); + let parent = t!(repo.refname_to_id("refs/heads/master")); + let parent = t!(repo.find_commit(parent)); + t!(repo.commit(Some("HEAD"), &sig, &sig, + "Another commit", &tree, + &[&parent])); + } } fn make_archive(&self) { @@ -233,7 +246,12 @@ impl Package { } pub fn archive_dst(&self) -> PathBuf { - dl_path().join(&self.name).join(&self.vers).join("download") + if self.local { + registry_path().join(format!("{}-{}.crate", self.name, + self.vers)) + } else { + dl_path().join(&self.name).join(&self.vers).join("download") + } } } diff --git a/tests/local-registry.rs b/tests/local-registry.rs new file mode 100644 index 000000000..906e7cde2 --- /dev/null +++ b/tests/local-registry.rs @@ -0,0 +1,343 @@ +#[macro_use] +extern crate cargotest; +extern crate hamcrest; + +use std::fs::{self, File}; +use std::io::prelude::*; + +use cargotest::support::paths::{self, CargoPathExt}; +use cargotest::support::registry::Package; +use cargotest::support::{project, execs}; +use hamcrest::assert_that; + +fn setup() { + let root = paths::root(); + t!(fs::create_dir(&root.join(".cargo"))); + t!(t!(File::create(root.join(".cargo/config"))).write_all(br#" + [source.crates-io] + registry = 'https://wut' + replace-with = 'my-awesome-local-registry' + + [source.my-awesome-local-registry] + local-registry = 'registry' + "#)); +} + +#[test] +fn simple() { + setup(); + Package::new("foo", "0.0.1") + .local(true) + .file("src/lib.rs", "pub fn foo() {}") + .publish(); + + let p = project("bar") + .file("Cargo.toml", r#" + [project] + name = "bar" + version = "0.0.1" + authors = [] + + [dependencies] + foo = "0.0.1" + "#) + .file("src/lib.rs", r#" + extern crate foo; + pub fn bar() { + foo::foo(); + } + "#); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stderr(&format!("\ +[UNPACKING] foo v0.0.1 ([..]) +[COMPILING] foo v0.0.1 +[COMPILING] bar v0.0.1 ({dir}) +", + dir = p.url()))); + assert_that(p.cargo("build"), execs().with_status(0).with_stderr("")); + assert_that(p.cargo("test"), execs().with_status(0)); +} + +#[test] +fn multiple_versions() { + setup(); + Package::new("foo", "0.0.1").local(true).publish(); + Package::new("foo", "0.1.0") + .local(true) + .file("src/lib.rs", "pub fn foo() {}") + .publish(); + + let p = project("bar") + .file("Cargo.toml", r#" + [project] + name = "bar" + version = "0.0.1" + authors = [] + + [dependencies] + foo = "*" + "#) + .file("src/lib.rs", r#" + extern crate foo; + pub fn bar() { + foo::foo(); + } + "#); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stderr(&format!("\ +[UNPACKING] foo v0.1.0 ([..]) +[COMPILING] foo v0.1.0 +[COMPILING] bar v0.0.1 ({dir}) +", + dir = p.url()))); + + Package::new("foo", "0.2.0") + .local(true) + .file("src/lib.rs", "pub fn foo() {}") + .publish(); + + assert_that(p.cargo("update").arg("-v"), + execs().with_status(0).with_stderr("\ +[UPDATING] foo v0.1.0 -> v0.2.0 +")); +} + +#[test] +fn multiple_names() { + setup(); + Package::new("foo", "0.0.1") + .local(true) + .file("src/lib.rs", "pub fn foo() {}") + .publish(); + Package::new("bar", "0.1.0") + .local(true) + .file("src/lib.rs", "pub fn bar() {}") + .publish(); + + let p = project("local") + .file("Cargo.toml", r#" + [project] + name = "local" + version = "0.0.1" + authors = [] + + [dependencies] + foo = "*" + bar = "*" + "#) + .file("src/lib.rs", r#" + extern crate foo; + extern crate bar; + pub fn local() { + foo::foo(); + bar::bar(); + } + "#); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stderr(&format!("\ +[UNPACKING] [..] +[UNPACKING] [..] +[COMPILING] [..] +[COMPILING] [..] +[COMPILING] local v0.0.1 ({dir}) +", + dir = p.url()))); +} + +#[test] +fn interdependent() { + setup(); + Package::new("foo", "0.0.1") + .local(true) + .file("src/lib.rs", "pub fn foo() {}") + .publish(); + Package::new("bar", "0.1.0") + .local(true) + .dep("foo", "*") + .file("src/lib.rs", "extern crate foo; pub fn bar() {}") + .publish(); + + let p = project("local") + .file("Cargo.toml", r#" + [project] + name = "local" + version = "0.0.1" + authors = [] + + [dependencies] + foo = "*" + bar = "*" + "#) + .file("src/lib.rs", r#" + extern crate foo; + extern crate bar; + pub fn local() { + foo::foo(); + bar::bar(); + } + "#); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stderr(&format!("\ +[UNPACKING] [..] +[UNPACKING] [..] +[COMPILING] foo v0.0.1 +[COMPILING] bar v0.1.0 +[COMPILING] local v0.0.1 ({dir}) +", + dir = p.url()))); +} + +#[test] +fn path_dep_rewritten() { + setup(); + Package::new("foo", "0.0.1") + .local(true) + .file("src/lib.rs", "pub fn foo() {}") + .publish(); + Package::new("bar", "0.1.0") + .local(true) + .dep("foo", "*") + .file("Cargo.toml", r#" + [project] + name = "bar" + version = "0.1.0" + authors = [] + + [dependencies] + foo = { path = "foo", version = "*" } + "#) + .file("src/lib.rs", "extern crate foo; pub fn bar() {}") + .file("foo/Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("foo/src/lib.rs", "pub fn foo() {}") + .publish(); + + let p = project("local") + .file("Cargo.toml", r#" + [project] + name = "local" + version = "0.0.1" + authors = [] + + [dependencies] + foo = "*" + bar = "*" + "#) + .file("src/lib.rs", r#" + extern crate foo; + extern crate bar; + pub fn local() { + foo::foo(); + bar::bar(); + } + "#); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stderr(&format!("\ +[UNPACKING] [..] +[UNPACKING] [..] +[COMPILING] foo v0.0.1 +[COMPILING] bar v0.1.0 +[COMPILING] local v0.0.1 ({dir}) +", + dir = p.url()))); +} + +#[test] +fn invalid_dir_bad() { + setup(); + let p = project("local") + .file("Cargo.toml", r#" + [project] + name = "local" + version = "0.0.1" + authors = [] + + [dependencies] + foo = "*" + "#) + .file("src/lib.rs", "") + .file(".cargo/config", r#" + [source.crates-io] + registry = 'https://wut' + replace-with = 'my-awesome-local-directory' + + [source.my-awesome-local-directory] + local-registry = '/path/to/nowhere' + "#); + + + assert_that(p.cargo_process("build"), + execs().with_status(101).with_stderr("\ +[ERROR] failed to load source for a dependency on `foo` + +Caused by: + Unable to update registry https://[..] + +Caused by: + failed to update replaced source `registry https://[..]` + +Caused by: + local registry path is not a directory: [..]path[..]to[..]nowhere +")); +} + +#[test] +fn different_directory_replacing_the_registry_is_bad() { + setup(); + + // Move our test's .cargo/config to a temporary location and publish a + // registry package we're going to use first. + let config = paths::root().join(".cargo"); + let config_tmp = paths::root().join(".cargo-old"); + t!(fs::rename(&config, &config_tmp)); + + let p = project("local") + .file("Cargo.toml", r#" + [project] + name = "local" + version = "0.0.1" + authors = [] + + [dependencies] + foo = "*" + "#) + .file("src/lib.rs", ""); + p.build(); + + // Generate a lock file against the crates.io registry + Package::new("foo", "0.0.1").publish(); + assert_that(p.cargo("build"), execs().with_status(0)); + + // Switch back to our directory source, and now that we're replacing + // crates.io make sure that this fails because we're replacing with a + // different checksum + config.rm_rf(); + t!(fs::rename(&config_tmp, &config)); + Package::new("foo", "0.0.1") + .file("src/lib.rs", "invalid") + .local(true) + .publish(); + + assert_that(p.cargo("build"), + execs().with_status(101).with_stderr("\ +[ERROR] checksum for `foo v0.0.1` changed between lock files + +this could be indicative of a few possible errors: + + * the lock file is corrupt + * a replacement source in use (e.g. a mirror) returned a different checksum + * the source itself may be corrupt in one way or another + +unable to verify that `foo v0.0.1` was the same as before in any situation + +")); +} diff --git a/tests/registry.rs b/tests/registry.rs index b4d473582..0ddb55999 100644 --- a/tests/registry.rs +++ b/tests/registry.rs @@ -160,7 +160,7 @@ fn bad_cksum() { let pkg = Package::new("bad-cksum", "0.0.1"); pkg.publish(); - File::create(&pkg.archive_dst()).unwrap(); + t!(File::create(&pkg.archive_dst())); assert_that(p.cargo_process("build").arg("-v"), execs().with_status(101).with_stderr("\ @@ -418,7 +418,7 @@ fn yanks_in_lockfiles_are_ok() { assert_that(p.cargo("build"), execs().with_status(0)); - fs::remove_dir_all(®istry::registry_path().join("3")).unwrap(); + registry::registry_path().join("3").rm_rf(); Package::new("bar", "0.0.1").yanked(true).publish(); @@ -575,7 +575,7 @@ fn dev_dependency_not_used() { #[test] fn login_with_no_cargo_dir() { let home = paths::home().join("new-home"); - fs::create_dir(&home).unwrap(); + t!(fs::create_dir(&home)); assert_that(cargo_process().arg("login").arg("foo").arg("-v"), execs().with_status(0)); } @@ -640,7 +640,7 @@ fn updating_a_dep() { ", dir = p.url()))); - t!(File::create(&p.root().join("a/Cargo.toml"))).write_all(br#" + t!(t!(File::create(&p.root().join("a/Cargo.toml"))).write_all(br#" [project] name = "a" version = "0.0.1" @@ -648,7 +648,7 @@ fn updating_a_dep() { [dependencies] bar = "0.1.0" - "#).unwrap(); + "#)); Package::new("bar", "0.1.0").publish(); println!("second"); @@ -740,7 +740,7 @@ fn update_publish_then_update() { Package::new("a", "0.1.1").publish(); let registry = paths::home().join(".cargo/registry"); let backup = paths::root().join("registry-backup"); - fs::rename(®istry, &backup).unwrap(); + t!(fs::rename(®istry, &backup)); // Generate a Cargo.lock with the newer version, and then move the old copy // of the registry back into place. @@ -757,9 +757,9 @@ fn update_publish_then_update() { .file("src/main.rs", "fn main() {}"); assert_that(p2.cargo_process("build"), execs().with_status(0)); - fs::remove_dir_all(®istry).unwrap(); - fs::rename(&backup, ®istry).unwrap(); - fs::rename(p2.root().join("Cargo.lock"), p.root().join("Cargo.lock")).unwrap(); + registry.rm_rf(); + t!(fs::rename(&backup, ®istry)); + t!(fs::rename(p2.root().join("Cargo.lock"), p.root().join("Cargo.lock"))); // Finally, build the first project again (with our newer Cargo.lock) which // should force an update of the old registry, download the new crate, and @@ -1125,16 +1125,12 @@ fn disallow_network() { assert_that(p.cargo("build").arg("--frozen"), execs().with_status(101).with_stderr("\ -[UPDATING] registry `[..]` error: failed to load source for a dependency on `foo` Caused by: Unable to update registry [..] Caused by: - failed to fetch `[..]` - -Caused by: - attempting to update a git repository, but --frozen was specified + attempting to make an HTTP request, but --frozen was specified ")); } -- 2.30.2